<template>
  <div class="main">
    <div class="topTitle">{{ props.title }}</div>
    <div class="form_content">
      <NScrollbar>
        <NSpin :show="spinShow">
          <div class="content">
            <NForm ref="formRef" :model="formValue" :rules="rules" label-placement="left" :label-width="80"
              label-align="right" style="width: 950rem" require-mark-placement="left">
              <NSpace justify="space-between">
                <NFormItem label="绑定功能" path="workflowEntity.functionCode">
                  <NSelect v-model:value="formValue.workflowEntity.functionCode" :options="parentCodeList"
                    placeholder="请选择绑定功能" class="commonWidth" value-field="value" label-field="name" filterable />
                </NFormItem>
                <NFormItem label="流程名称" path="workflowEntity.entityName">
                  <NInput :allow-input="stopNull" v-model:value="formValue.workflowEntity.entityName"
                    placeholder="请输入流程名称" class="commonWidth" />
                </NFormItem>
              </NSpace>

              <NSpace justify="space-between">
                <NFormItem label="流程状态" path="workflowEntity.entityStatusFlag">
                  <NSelect v-model:value="formValue.workflowEntity.entityStatusFlag" :options="ProgressStauts"
                    placeholder="请选择流程状态" class="commonWidth" />
                </NFormItem>
                <NFormItem label="允许加签" path="workflowEntity.assigneeFlag">
                  <NSelect v-model:value="formValue.workflowEntity.assigneeFlag" :options="assignList"
                    placeholder="请选择加签状态" class="commonWidth" />
                </NFormItem>
              </NSpace>

              <NSpace justify="space-between">
                <NFormItem label="结束通知" path="workflowEntity.sendMessage">
                  <NSelect v-model:value="formValue.workflowEntity.sendMessage" :options="[
                    { label: '开启', value: 1 },
                    { label: '关闭', value: 0 }
                  ]" placeholder="请选择流程状态" class="commonWidth" />
                </NFormItem>
                <NFormItem label="重新审批" path="workflowEntity.fallbackFlag"
                  v-if="['A0518', 'A0533'].includes(formValue.workflowEntity.functionCode)">
                  <NSelect v-model:value="formValue.workflowEntity.fallbackFlag" :options="[
                    { label: '允许重新审批', value: 1 },
                    { label: '禁止重新审批', value: 0 }
                  ]" placeholder="请选择是否允许重新审批" class="commonWidth" />
                </NFormItem>
              </NSpace>

              <NFormItem label="审批规则" path="workflowConfigList">
                <NButton type="primary" ghost style="width: 110rem" @click="formValue.workflowConfigList.unshift({})">
                  新增规则
                </NButton>
              </NFormItem>

              <div class="ruleItem" v-for="(item, index) in formValue.workflowConfigList" :key="index">
                <div class="leftItem">
                  <div style="height: auto">
                    <span style="font-size: 14rem; margin-right: 15rem">适用范围</span>
                    <NButton type="primary" style="height: 30rem" @click="openScope('范围', index)">
                      选择范围
                    </NButton>
                  </div>
                  <div style="margin: 5rem 0">
                    {{ item.workflowConfigUserScopeList?.map((it: any) => it.typeName).join('，') }}
                  </div>
                  <div style="height: auto">
                    <span style="font-size: 14rem; margin-right: 15rem">审批步骤</span>
                    <NButton type="primary" style="height: 30rem" @click="openScope('步骤', index)">
                      选择步骤
                    </NButton>
                  </div>
                  <div style="margin-top: 5rem">
                    {{
                      item.workflowConfigApprovalNodeList?.map((it: any) => it.typeName).join(' → ')
                    }}
                  </div>
                </div>
                <div class="rightItem">
                  <div class="upLow">
                    <NIcon size="28" style="cursor: pointer" @click="moveSort(index, 'add')">
                      <ArrowUpwardSharp />
                    </NIcon>
                    <NIcon size="28" style="cursor: pointer" @click="moveSort(index, 'lose')">
                      <ArrowDownwardOutlined />
                    </NIcon>
                  </div>
                  <div class="delete">
                    <NIcon size="24" style="cursor: pointer" @click="formValue.workflowConfigList.splice(index, 1)">
                      <CloseFilled />
                    </NIcon>
                  </div>
                </div>
              </div>

              <NFormItem label="通知人" path="remarks">
                <div style="display: flex; align-items: flex-start; width: 100%">
                  <NButton type="primary" ghost style="height: 44rem; width: 110rem" @click="openScope('通知人')">
                    选择通知人
                  </NButton>
                  <span class="notice-box" style="display: inline;">
                    {{
                      formValue.workflowMakeCopyList?.map((it: any) => it.typeName).join('，')
                    }}
                  </span>
                </div>
              </NFormItem>

              <NFormItem label="说明" path="workflowEntity.remark">
                <NInput v-model:value="formValue.workflowEntity.remark" placeholder="请输入说明" type="textarea"
                  style="min-height: 150rem" :allow-input="stopNull" />
              </NFormItem>

            </NForm>
          </div>
        </NSpin>
      </NScrollbar>
    </div>
  </div>
  <FixedAction>
    <div style="display: flex">
      <NSpace justify="start" style="flex: 0 0 42%">
        <NButton style="width: 78px; color: #5fb17f" ghost @click="goBack">
          <template #icon>
            <img :src="VBackImg" style="width: 25rem; height: 25rem" />
          </template>
          返回
        </NButton>
      </NSpace>

      <NSpace justify="center">
        <NButton type="primary" @click="confirm" :loading="loading">
          保存流程
        </NButton>
      </NSpace>
    </div>
  </FixedAction>

  <NModal :auto-focus="false" v-model:show="modalVisible" @close="modalVisible = false">
    <VScope @close="modalVisible = false" @scopeSubmit="getScopeList" :defaultList="scopeList" :selectFlat="selectFlat" />
  </NModal>

  <NModal :auto-focus="false" v-model:show="contentVisible" @close="contentVisible = false">
    <VDialogContent @close="contentVisible = false" @submit="submit" title="保存提示" :submitFlat="checkFolw">
      <div style="
          width: 300rem;
          min-height: 100rem;
          height: auto;
          text-align: center;
          display: flex;
          align-items: center;
          justify-content: center;
        ">
        {{ checkFolw == false ? '当前已有相关流程，请在列表页更改相关流程状态!' : checkFolw == true ? '您确定要保存吗？' : '' }}
      </div>
    </VDialogContent>
  </NModal>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive, watch } from 'vue'
import {
  NSpace,
  NForm,
  NInput,
  NFormItem,
  NButton,
  NScrollbar,
  useMessage,
  NSelect,
  NIcon,
  NModal,
  NSpin
} from 'naive-ui'
import type { FormInst } from 'naive-ui'
import router from '@/router'
import { useTagStore } from '@/stores/layout'
import FixedAction from '@/components/FixedAction.vue'
import { sendRequest } from '@/utils/api'
import type { HttpResponse } from '@/utils/http'
import { useRoute } from 'vue-router'
import { ArrowUpwardSharp, ArrowDownwardOutlined, CloseFilled } from '@vicons/material'
import VScope from '../../Common/Scope.vue'
import VDialogContent from '@/views/OA/Common/DialogContent.vue'
import VBackImg from '@/assets/images/back.png'

const message = useMessage()
const tags = useTagStore().tags
const route = useRoute()
const modalVisible = ref(false)

const props = defineProps({
  title: { type: String, default: () => '流程新增' },
  id: { type: [Number, String], default: () => null }
})
//流程状态
const ProgressStauts: any = [
  {
    value: 0,
    label: '禁用'
  },
  {
    value: 1,
    label: '启用'
  }
]
//允许加签
const assignList: any = [
  {
    value: 0,
    label: '禁止加签'
  },
  {
    value: 1,
    label: '允许加签'
  }
]

const formRef = ref<FormInst | null>(null)
const formValue = reactive<Record<string, any>>({
  workflowEntity: {
    entityName: null, //流程名称
    assigneeFlag: 0, //加签
    entityStatusFlag: 0, //流程状态
    functionCode: null, //绑定功能
    remark: null, //备注说明
    sendMessage: 0,//是否通知
    fallbackFlag: 0,//重新审批
    id: null
  },
  workflowConfigList: [],
  workflowMakeCopyList: [] //通知人
})
const rules: any = {
  workflowEntity: {
    entityName: {
      required: true,
      trigger: ['blur', 'input'],
      validator: (_: any, value: any) => {
        if (!value) return new Error('请输入流程名称')
        if (value.length > 100) return new Error('流程名称字数不得超过100')
        return true
      }
    },
    remark: {
      required: false,
      trigger: ['blur', 'input'],
      validator: (_: any, value: any) => {
        if (value?.length > 100) return new Error('说明字数不得超过100')
        return true
      }
    },
    functionCode: {
      required: true,
      message: '请选择绑定功能',
      trigger: ['change', 'select']
    },
    entityStatusFlag: {
      required: true,
      type: 'any',
      message: '请选择流程状态',
      trigger: ['change', 'select']
    }
  },
  workflowConfigList: {
    required: true,
    type: 'array',
    message: '请配置审批规则',
    trigger: ['change', 'select']
  }
}
//去除空格
const stopNull = (value: string) => {
  return !value.startsWith(' ') && !value.endsWith(' ')
}
// 移动index
const moveSort = (index: any, status: any) => {
  if (status == 'add') {
    if (index == 0) return
    formValue.workflowConfigList.splice(
      index,
      1,
      ...formValue.workflowConfigList.splice(index - 1, 1, formValue.workflowConfigList[index])
    )
  }
  if (status == 'lose') {
    if (index == formValue.workflowConfigList.length - 1) return
    formValue.workflowConfigList.splice(
      index + 1,
      1,
      ...formValue.workflowConfigList.splice(index, 1, formValue.workflowConfigList[index + 1])
    )
  }
}
// 范围选择确定
const getScopeList = (v: any) => {
  if (scopeName.value == '范围')
    formValue.workflowConfigList[scopeIndex.value].workflowConfigUserScopeList = v
  if (scopeName.value == '步骤')
    formValue.workflowConfigList[scopeIndex.value].workflowConfigApprovalNodeList = v
  if (scopeName.value == '通知人') formValue.workflowMakeCopyList = v
  modalVisible.value = false
}
// 打开发布范围
const scopeList = ref()
const scopeName = ref()
const scopeIndex = ref()
const selectFlat = ref(false)
const openScope = (v: any, index = 0) => {
  if (v == '范围') scopeList.value = formValue.workflowConfigList[index].workflowConfigUserScopeList
  if (v == '步骤')
    scopeList.value = formValue.workflowConfigList[index].workflowConfigApprovalNodeList
  if (v == '通知人') scopeList.value = formValue.workflowMakeCopyList
  v == '步骤' ? (selectFlat.value = true) : (selectFlat.value = false)
  scopeName.value = v
  scopeIndex.value = index
  modalVisible.value = true
}
//绑定信息
const parentCodeList: any = ref([])
const getFunction = async () => {
  const [error, res] = await sendRequest<HttpResponse>({
    module: 'progress',
    api: 'getWorkFlowFunctionCodeList',
  })
  if (error) return message.error(error.message)
  parentCodeList.value = res.data
}
//回显信息
const spinShow = ref(false)
const getInfo = async () => {
  spinShow.value = true
  const [error, res] = await sendRequest<HttpResponse>({
    module: 'progress',
    api: 'progressInfo',
    uri: {
      id: props.id
    }
  })
  if (error) return message.error(error.message)
  formValue.workflowEntity = res.data.workflowEntity
  formValue.workflowEntity.sendMessage = formValue.workflowEntity.sendMessage ? 1 : 0
  formValue.workflowEntity.fallbackFlag = formValue.workflowEntity.fallbackFlag ? 1 : 0
  formValue.workflowConfigList = res.data.workflowConfigList
  formValue.workflowMakeCopyList = res.data.workflowMakeCopyList
  spinShow.value = false
}
// 返回
const goBack = () => {
  const index = tags.findIndex((item: any) => item.path === router.currentRoute.value.fullPath)
  tags.splice(index, 1)
  if (tags.length == 0) {
    router.push({ path: '/OA/Workbench/UserDesktop' })
  } else history.back()
}
//检查约束
const checkFolw: any = ref()
const getCheckWorkflowEntity = async () => {
  const [error, res] = await sendRequest<HttpResponse>({
    module: 'progress',
    api: 'checkWorkflowEntity',
    override: {
      params: {
        functionCode: formValue.workflowEntity.functionCode,
        entityId: props.id
      }
    }
  })
  if (error) return message.error(error.message)
  checkFolw.value = res.data
}
// 确定
const loading = ref(false)
const confirm = () => {
  formRef.value?.validate(async (err: any) => {
    if (err) return
    const listUser: any = []
    const listApprove: any = []
    if (!formValue.workflowConfigList.length) return message.error('请配置审批规则')
    const flatUser = formValue.workflowConfigList.every((it: any) => it.workflowConfigUserScopeList?.length)
    const flatApprove = formValue.workflowConfigList.every((it: any) => it.workflowConfigApprovalNodeList?.length)
    if (!flatUser || !flatApprove) {
      const flatIndex1 = formValue.workflowConfigList.findIndex((it: any) => !it.workflowConfigUserScopeList?.length)
      if (flatIndex1 !== -1) return message.error('第 ' + (flatIndex1 + 1) + ' 条审批规则适用范围/审批步骤为空')
      const flatIndex2 = formValue.workflowConfigList.findIndex((it: any) => !it.workflowConfigApprovalNodeList?.length)
      if (flatIndex2 !== -1) return message.error('第' + (flatIndex2 + 1) + '条审批规则适用范围/审批步骤为空')
    }
    for (let i = 0; i < formValue.workflowConfigList.length; i++) {
      listUser.push(formValue.workflowConfigList[i].workflowConfigUserScopeList?.map((it: any) => it.typeName).join('，'))
      listApprove.push(formValue.workflowConfigList[i].workflowConfigApprovalNodeList?.map((it: any) => it.typeName).join('，'))
    }
    // 找到相同流程配置的index并且提示
    const flat1 = isAllEqual(listUser)
    const flat2 = isAllEqual(listApprove)
    if (flat1[0] && flat2[0] && formValue.workflowConfigList?.length > 1) {
      const indexList: any = []
      let indexNum = null
      formValue.workflowConfigList.map((it: any, index: any) => {
        const i = it.workflowConfigUserScopeList?.map((it: any) => it.typeName).join('，')
        const c = it.workflowConfigApprovalNodeList?.map((it: any) => it.typeName).join('，')
        if (i == flat1[1][0] && c == flat2[1][0]) indexList.push(index)
      })
      if (indexList.length > 0) indexNum = indexList.map((it: any) => it + 1).join('/')
      return message.error('多条审批规则不可设置范围/步骤完全相同 ' + (indexNum ? '(' + indexNum + ')' : ''))
    }
    formValue.workflowEntity.entityStatusFlag == 0
      ? (checkFolw.value = true)
      : await getCheckWorkflowEntity()
    contentVisible.value = true
  })
}
// 判断是否相同
function isAllEqual(array: any) {
  let isFlat: any = []
  let indexTmp: any = []
  if (array.length > 1) {
    array.forEach((value: any) => {
      const tmp = array
      tmp.splice(tmp.findIndex((it: any) => it == value), 1)
      if (tmp[tmp.findIndex((it: any) => it == value)]) indexTmp.push(tmp[tmp.findIndex((it: any) => it == value)])
      return isFlat.push(tmp.some((it: any) => it == value))
    })
    return [isFlat.some((it: any) => it), indexTmp]
  }
  else return [true, []]
}
// 提交
const contentVisible = ref(false)
const submit = async () => {
  loading.value = true
  if (!checkFolw.value) return (contentVisible.value = false), (loading.value = false)
  const tmp = JSON.parse(JSON.stringify(formValue))
  tmp.sendMessage = tmp.sendMessage ? true : false
  console.log(tmp.workflowEntity.fallbackFlag)

  if (!['A0518', 'A0533'].includes(tmp.workflowEntity.functionCode)) tmp.workflowEntity.fallbackFlag = 0
  if (props.title == '新增流程') {
    const [error, res] = await sendRequest<HttpResponse>({
      module: 'progress',
      api: 'progressAdd',
      override: {
        data: {
          ...tmp
        }
      }
    })
    loading.value = false
    contentVisible.value = false
    if (error) return message.error(error.message)
    message.success(res.msg)
    goBack()
  } else {
    const [error, res] = await sendRequest<HttpResponse>({
      module: 'progress',
      api: 'progressUpdate',
      override: {
        data: {
          id: props.id,
          ...tmp
        }
      }
    })
    loading.value = false
    contentVisible.value = false
    if (error) return message.error(error.message)
    message.success(res.msg)
    goBack()
  }
}

watch(
  () => props.id,
  () => {
    if (props.title == '流程编辑' && props.id) getInfo()
  },
  { deep: true, immediate: true }
)
onMounted(() => {
  getFunction()
})
</script>

<style scoped lang="scss">
@mixin CommonFont {
  font-size: 16rem;
  font-family: PingFangSC, PingFang SC;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.85);
}

.commonWidth {
  width: 360rem;
}

.main {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow: hidden;

  .topTitle {
    width: 100%;
    border-bottom: 1px solid #fff;
    padding: 15rem 20rem;
    margin-bottom: 20rem;
    @include CommonFont;
  }

  .form_content {
    width: 100%;
    height: 100%;
    padding: 0 20rem 0rem;

    .content {
      display: flex;
      align-items: center;
      flex-direction: column;
      width: 100%;
      height: 100%;
      padding: 18rem 33rem 180rem;
      overflow-y: scroll;
      background-color: #ebeceb;

      .scope {
        width: 360rem;
        height: 130rem;
        background: #e1e1e1;
        margin-bottom: 25rem;
      }
    }

    .notice-box {
      flex: 1;
      min-height: 44rem;
      background: #ebeceb;
      border-radius: 2rem;
      border: 1rem solid #d9d9d9;
      margin-left: 10rem;
      padding: 0 10rem;
    }
  }
}

.content::-webkit-scrollbar {
  display: none;
}

.ruleItem {
  display: flex;
  align-items: center;
  width: 100%;
  height: auto;
  background: #e1e1e1;
  padding: 20rem 30rem 20rem 20rem;
  margin-bottom: 20rem;
  background-color: #e1e1e1;

  .leftItem {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    flex: 0 0 90%;
    height: 100%;
  }

  .rightItem {
    flex: 1;
    display: flex;
    align-items: center;
    height: 100%;

    .upLow {
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      margin-left: 20%;
      width: 60%;
      height: 100%;
    }

    .delete {
      display: flex;
      align-items: center;
      width: 20%;
      height: 100%;
    }
  }
}

:deep(.n-spin-container) {
  width: 100%;
  height: 100%;
}

:deep(.n-scrollbar-container) {
  width: 100%;
  height: 100%;
}

:deep(.n-scrollbar-content) {
  width: 100%;
  height: 100%;
}

:deep(.n-spin-content) {
  width: 100%;
  height: 100%;
}
</style>
